

#include "stdio.h"
#include "conio.h"
// WMDM includes
#include "mswmdm_i.c"
#include "mswmdm.h"
#include "sac.h"
#include "scclient.h"

#include "MTPDeviceManager.h"
#include "MTPDevice.h"
#include "MTPException.h"

using namespace System;
using namespace Collections;


MTPDeviceManager::MTPDeviceManager()
{
	CSecureChannelClient *pSacClient = new CSecureChannelClient();
	
	//these are generic keys
	BYTE abPVK[] = {0x00};
	BYTE abCert[] = {0x00};
	
	CoInitialize(NULL);

	IComponentAuthenticate* pICompAuth;

	// get an authentication interface
	HRESULT hr = CoCreateInstance(CLSID_MediaDevMgr, NULL, CLSCTX_ALL ,IID_IComponentAuthenticate, (void **)&pICompAuth);
	if SUCCEEDED(hr)
	{
		m_pICompAuth = (void *)pICompAuth;
		// create a secure channel client certificate
		hr = pSacClient->SetCertificate(SAC_CERT_V1, (BYTE*) abCert, sizeof(abCert), (BYTE*) abPVK, sizeof(abPVK));
		if SUCCEEDED(hr)
		{
			// bind the authentication interface to the secure channel client
			pSacClient->SetInterface(pICompAuth);

			// trigger communication
			hr = pSacClient->Authenticate(SAC_PROTOCOL_V1);                    
			if SUCCEEDED(hr)
			{
				// get main interface to media device manager
				IWMDeviceManager3* tmpComObj;
				hr = pICompAuth->QueryInterface(IID_IWMDeviceManager2, (void**)&tmpComObj);
				if FAILED(hr)
				{
					throw gcnew MTPException();
				}
				m_pIdvMgr = (void *)tmpComObj;
				// we now have a media device manager interface...
			}
		}
	}
}

MTPDeviceManager::~MTPDeviceManager()
{
	((IWMDeviceManager3*)m_pIdvMgr)->Release();
	((IComponentAuthenticate*)m_pICompAuth)->Release();
	
	CoUninitialize();
}

Collections::Generic::List<BaseDevice^>^ MTPDeviceManager::findDevices()
{
	Collections::Generic::List<BaseDevice^>^ deviceList = gcnew Collections::Generic::List<BaseDevice^>(); 
	
	// enumerate devices...
	IWMDMEnumDevice *pIEnumDev;

	HRESULT hr = ((IWMDeviceManager3*)m_pIdvMgr)->EnumDevices2(&pIEnumDev);
	if SUCCEEDED(hr) {
		hr = pIEnumDev->Reset(); // Next will now return the first device
		if SUCCEEDED(hr) {
			IWMDMDevice3* pIDevice;
			unsigned long ulNumFetched;
			MTPDevice^ device;
			hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
			while (SUCCEEDED(hr) && (hr != S_FALSE)) {
				device = gcnew MTPDevice((void *)pIDevice);
				deviceList->Add(device);

				// move to next device
				hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
			}
			pIEnumDev->Release();
		}
	}

	return deviceList;
}

